package com.example.tester.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *
 * RabbitMQ有四种Exchange类型，
 * 分别是
 *  1.Direct 直连交换机  DirectExchange是RabbitMQ Broker的默认Exchange，它有一个特别的属性对一些简单的应用来说是非常有用的，在使用这个类型的Exchange时，可以不必指定routing key的名字，在此类型下创建的Queue有一个默认的routing key，这个routing key一般同Queue同名
 *  2.Fanout 广播交换机  这种类型的Exchange，会忽略routing key的存在，直接将message广播到所有的Queue中
 *  3.Topic 主题交换机  根据routing key和Exchange的类型将message发送到一个或者多个Queue中，我们经常拿他来实现各种publish/subscribe，即发布订阅
 *  4.Headers        根据Message的一些头部信息来分发过滤Message，忽略routing key的属性，如果Header信息和message消息的头信息相匹配，那么这条消息就匹配上了。
 *
 * ----------------------
 * Fanout 不处理路由键。
 * 你只需要简单的将队列绑定到交换机上。一个发送到该类型交换机的消息都会被广播到与该交换机绑定的所有队列上
 *
 * Fanout 交换机适用场景
 *  1.大型玩家在玩在线游戏的时候，可以用它来广播重大消息
 *  2.体育新闻实时更新到手机客户端
 *  3.群聊功能，广播消息给当前群聊中的所有人
 *
 *
 * @author lzh
 * @date 2019/9/11 - 14:05
 */
@Configuration
public class RabbitFanoutConfig {

    /**
     * fanout
     */
    public static final String FANOUT_QUEUE1 = "fanout.queue1";
    public static final String FANOUT_QUEUE2 = "fanout.queue2";
    public static final String FANOUT_EXCHANGE = "fanout.exchange";



    /**
     * Fanout模式
     * Fanout 就是我们熟悉的广播模式或者订阅模式，
     * 给Fanout交换机发送消息，绑定了这个交换机的所有队列都收到这个消息。
     * @return
     */
    @Bean
    public Queue fanoutQueue1() {
        return new Queue(FANOUT_QUEUE1);
    }

    @Bean
    public Queue fanoutQueue2() {
        return new Queue(FANOUT_QUEUE2);
    }

    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(FANOUT_EXCHANGE);
    }


    /**
     * 注意 Fanout 不处理路由键，这里不用配置routing key
     *
     * 只需要把队列和交换机绑定即可
     * @return
     */
    @Bean
    public Binding fanoutBinding1() {
        return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
    }

    @Bean
    public Binding fanoutBinding2() {
        return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
    }



}
